<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>17.1.2-Block 与 PatchFlags</title>
</head>
<body>
    <!-- 虚拟节点参考例子 -->
    <div>
        <div>foo</div>
        <p>{{ bar }}</p>
    </div>

    <!-- 解释例子 -->
    <template>
        <!-- 这个 div 标签是一个 Block -->
        <div>
            <!-- 这个 p 标签不是 Block，因为它不是根节点 -->
            <p>{{ bar }}</p>
        </div>
        <!-- 这个 h1 标签是一个 Block -->
        <h1>
            <!-- 这个 span 标签不是 Block，因为它不是根节点 -->
            <span :id="dynamicId"></span>
        </h1>
    </template>
</body>
    <script>
        /**
         * 只要运行时能够区分动态内容和静态内容，即可实现极致的优化策略
         * 
         * - 当渲染器在更新一个 Block 时，会忽略虚拟节点的 children 数组，
         *    而是直接找到该虚拟节点的 dynamicChildren 数组，并只更新该数组中的动态节点。
         *    这样，在更新时就实现了跳过静态内容，只更新动态内容
         * - 由于动态节点中存在对应的补丁标志，所以在更新动态节点的时候，也能够做到靶向更新。
         *    例如，当一个动态节点的 patchFlag 值为数字 1 时，
         *     我们知道它只存在动态的文本节点，所以只需要更新它的文本内容即可
         * - 我们在编写模板代码的时候，所有模板的根节点都会是一个 Block 节点
        */



        /**
         * 传统的虚拟 DOM
         *  没有任何标志能够体现出节点的动态性
        */
        const vnode = {
            tag: 'div',
            children: [
                { tag: 'div', children: 'foo' },
                { tag: 'p', children: ctx.bar },
            ]
        }
        
        /**
         * 把补丁标志理解为一系列数字标记
        */
       const PatchFlags = {
           TEXT: 1,  // 代表节点有动态的 textContent
           CLASS: 2, // 代表元素有动态的 class 绑定
           STYLE: 3  // 代表元素有动态的 style 绑定
           // 其他……
       }

        /**
         * 编译优化之后
         *  编译器会将它提取到的关键信息 “附着” 到虚拟DOM 节点上
         * 
         * 把它的动态子节点提取出来，并将其存储到该虚拟节点的 dynamicChildren 数组内
         * 把带有该属性(dynamicChildren)的虚拟节点称为 “块”，即 Block
         * 一个 Block 不仅能够收集它的直接动态子节点，还能够收集所有动态子代节点
         * 
        */
        const vnode1 = {
            tag: 'div',
            children: [
                { tag: 'div', children: 'foo' },
                { tag: 'p', children: ctx.bar, patchFlag: PatchFlags.TEXT },  // 这是动态节点
            ],
            // 将 children 中的动态节点提取到 dynamicChildren 数组中
            dynamicChildren: [
                // p 标签具有 patchFlag 属性，因此它是动态节点
                { tag: 'p', children: ctx.bar, patchFlag: PatchFlags.TEXT }
            ]
        }

        

    </script>
    

</html>